package com.yx.controller;

import com.alibaba.fastjson.JSON;
import com.yx.common.R;
import com.yx.constatns.RabbitMQConstatns;
import com.yx.feign.api.GoodsService;
import com.yx.vo.Goods;
import com.yx.vo.GoodsType;
import com.yx.vo.Stock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @Classname GoodsController
 * @Date 2021/07/08 16:30
 * @Author by yx
 * @Description TODO:
 */
@Controller
@RequestMapping("/goodsController")
@Slf4j
public class GoodsController {

    @Autowired
    private GoodsService goodsService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("/{page}.html")
    public String toPage(@PathVariable String page) {
        return "goods/" + page;
    }

    @GetMapping("/getGoodsList")
    public String getGoodsList(ModelMap modelMap) {
        List<Goods> goodsList = goodsService.getGoodsList();
        modelMap.put("goodsList", goodsList);
        //不使用 @ResponseBody 注释,默认寻找视图
        return "goods/goodsList";
    }

    @PostMapping("/addGoods")
    @ResponseBody
    public R addGoods(Goods goods) {

        /*
        * 此方法存在分布式事务问题,
        * 调用了两次goods服务分别完成商品表和库存表的插入,
        * 存在以下问题:goods表成功,stock表未成功,结果是goods插入成功,stock插入失败
        * 而我们要的结果是,一旦插入失败,需要全部回滚,故此种方法存在分布式事务问题
        * 解决方法: 使用分布式事务完成
        * 解决方法二: 分析业务,发现调用的是同一个服务,可使用本地事务,在事务中向两张数据表插入数据,保证了事务
        * 原因: goods服务中goods实体类没有stock属性,故一开始采用了数据回填,调用两次服务的做法,由此引发了分布式事务问题
        * 归根结底,是stock属性引发的问题,故重新创建一个vo实体类goods,将stock属性携带过去,在goods服务中再根据数据库entity实体类进行拆分,即可使用本地事务解决整个问题
        * 备注: 分布式事务极大消耗系统资源,能不用分布式事务就不用分布式事务,最佳解决方案为:本地事务.
        * */
       /* //获取回填id的goods
        Goods dbGoods = goodsService.addGoods(goods);

        Stock stock = new Stock();
        stock.setGid(dbGoods.getId());
        //回填的dbGoods中没有Gstock
        stock.setStock(goods.getGstock());

        goodsService.addStock(stock);*/

        // 向数据库中添加数据
        Goods dbGoods = goodsService.addGoodsAndStock(goods);

        String json = JSON.toJSONString(dbGoods);

        // 向es中添加数据,采用消息队列的方式
        rabbitTemplate.convertAndSend(RabbitMQConstatns.GOODS_EXCHANGE, "shop.goods.insert", json);
        //将数据发送给item,生成商品静态页面
        rabbitTemplate.convertAndSend(RabbitMQConstatns.GOODS_EXCHANGE, "shop.item.insert", json);



        return R.success();
    }

    @GetMapping("/UpdateGoods/{id}")
    public String UpdateGoodsById(@PathVariable("id") Integer id, ModelMap modelMap) {
        Goods goods = goodsService.getGoodById(id);
        Stock stock = goodsService.getStockByGid(goods.getId());
        goods.setGstock(stock.getStock());
        //获取父类型
        List<GoodsType> goodsTypeList = goodsService.getGoodsTypeListByPid(-1);
        modelMap.put("goodsTypeList",goodsTypeList);
        modelMap.put("goods", goods);
        return "goods/editGoods";
    }

    @PostMapping("/updateGoods")
    @ResponseBody
    public R updateGoods(Goods goods) {
        return R.write(goodsService.updateGoods(goods));
    }

}
